PHP Core / OOPs / abstract class Vs Interface
Abstract class vs Interfaces
-
Note
1. What
Interface and Abstract class are used to achieve polymorphism.
2. When to use
When to use an abstract class- a. An abstract class is a good choice if we are using the inheritance concept since it provides a common base class implementation to derived classes.
- b. An abstract class is also good if we want to declare non-public members. In an interface, all methods must be public.
- c. If we want to add new methods in the future, then an abstract class is a better choice. Because if we add new methods to an interface, then all of the classes that already implemented that interface will have to be changed to implement the new methods.
- d. If we want to create multiple versions of our component, create an abstract class. Abstract classes provide a simple and easy way to version our components. By updating the base class, all inheriting classes are automatically updated with the change. Interfaces, on the other hand, cannot be changed once created. If a new version of an interface is required, we must create a whole new interface.
- e. Abstract classes have the advantage of allowing better forward compatibility. Once clients use an interface, we cannot change it; if they use an abstract class, we can still add behavior without breaking the existing code.
- f. If we want to provide common, implemented functionality among all implementations of our component, use an abstract class. Abstract classes allow us to partially implement our class, whereas interfaces contain no implementation for any members.
- Interfaces are also good when we want to have something similar to multiple inheritances since we can implement multiple interfaces.
- Multiple Inheritance cannot be achieved using Abstract whereas with Interface we can achieve it.
- An interface do not have public, private , protected , internal etc. access modifiers because in an interface by default everything is public.
3. Scenario
Interface is used when you want to define a contract and you don't know anything about implementation. (here it is total abstraction as you don't know anything.)
Abstract class:Abstract class is used when you know something and rely on others for what you don't know.(here it is partial abstraction as some of the things you know and some you don't know.)
Interface Scenario 1: When you know the contract methods but don't know anything about the implementationConsider we want to start a service like "makemytrip.com" or "expedia.com", where we are responsible for displaying the flights from various flight service company and place an order from customer. Lets keep our service as simple as,
- Displaying flights available from vendors like "airasia", "british airways" and "emirates".
- Place and order for seat to respective vendor.
Remember, In this application, we don't own any flight. we are just a middle man/aggregator and our task is to first enquire "airasia", then enquire "british airways" and at last enquire "emirates" about the list of flights available and later if customer opts for booking then inform the respective flight vendor to do booking.
For this, first we need to tell "airasia", "british airways" and "emirates" to give us list of flights, internally how they are giving the list that we don't care
- 1. This means I only care for method "getAllFlights()"
- a. "getAllFlights()" from "airasia" may have used SOAP service to return list of flights.
- b. "getAllFlights()" from "british airways" may have used REST service to return list of flights.
- c. "getAllFlights()" from "emirates" may have used CORBA service to return list of flights.
but we don't care how it is internally implemented and what we care is the contract method "getAllFlights" that all the flight vendor should provide and return list of flights.
- 2. Similarly, for booking I only care for method "doBooking()" that all vendors should have, internally how this vendors are doing booking that I don't care.
In this situation, Interface is useful because we are not aware of the implementation of all the 2 methods required, and what we know is the contract methods that vendor(implementer) should provide. so due to this total abstraction and for defining the contract, interface is useful in this place. Interface scenario 2: Your contract implementation can change in future.we want to develop some business application which require usage of Database and we choose to use Oracle. So we will design something like below,
We are using Oracle database and all our layers are binded to use OracleDatabaseManager to fetch data using Oracle database.
Now, say tomorrow we plan to change our database to Postgresql, We will end up changing all our layers, which is wrong. If we need to change all our layers, imagine testing and development efforts required.
So how our design should be which can sustain future changes ? Interface will come to rescue. Instead of using calling concrete implementation menthods in service layer, we should call contract methods of interface which doesn't know anything about implementation.
In this appraoch, Service layer doesn't care as which implementation we are using.
So in future if we switch from Oracle to PostgreSQL or to any vendor, Service layer will have no impact and it will remain as it is because it calls interface contract methods which doesn't care about implementation.
Only change required is in Database layer which is also a minimal change.
Also, this design helps us adding more vendor as an when required without disturbing the existing vendor implementation.
So we can say that our application or our service layer is not tightly coupled with database layer instead both layer works on contract which make them loosely coupled and changes on one layer doesn't affect another layer as contract still remains same.
Abstract Scenario 1 : Developer konw the implementation of some function. He don't know implementation of some other functionsConsider we want to start a service like Bulk SMS sender, where we take orders from various telecom vendors like Airtel, France Telecom, Vodafone etc.
For this, we don't have to setup your own infrastructure for sending SMS like Mobile towers but we need to take care of government rules like after 9PM, we should not send promotional SMS, we should also not send SMS to users registered under Do Not Disturb(DND) service etc. Remember, we need to take care of government rules for all the countries where we are sending SMS.
Example, In case of,
- a. Vodafone request us for bulk messaging, in that case we will use Vodafine towers to send SMS.
- b. Airtel request us for bulk messaging, in that case we will use Airtel towers to send SMS.
- c. What our job is to manage Telecom Regulations for different countries where we are sending SMS.
public void eastablishConnectionWithYourTower(){ //connect using vendor way. //we don't know how, candidate for abstract method } public void sendSMS(){ eastablishConnectionWithYourTower(); checkForDND(); checkForTelecomRules(); //sending SMS to numbers...numbers. destroyConnectionWithYourTower() } public void destroyConnectionWithYourTower(){ //disconnect using vendor way. //we don't know how, candidate for abstract method } public void checkForDND(){ //check for number present in DND. } public void checkForTelecomRules(){ //Check for telecom rules. } Out of above 5 methods,
- 1. Methods we know is "sendSMS()", "checkForDND()", "checkForTelecomRules()".
- 2. Methods we don't know is "eastablishConnectionWithYourTower()", "destroyConnectionWithYourTower()".
we know how to check government rules for sending SMS as that is what our job is but we don't how to eastablish connection with tower and how to destroy connection with tower because this is purely customer specific, airtel has its own way, vodafone has its own way etc.
In this case, Abstract class will be helpful, because you know partial things like "checkForDND()", "checkForTelecomRules()" for sending sms to users but we don't know how to eastablishConnectionWithTower() and destroyConnectionWithTower() and need to depend on vendor specific way to connect and destroy connection from their towers. Let's see how our class will look like,
Abstract Scenario 2 : the derived class must implement their own logicabstract class SMSSender{ abstract public void eastablishConnectionWithYourTower(); public void sendSMS(){ /*eastablishConnectionWithYourTower(); checkForDND(); checkForTelecomRules(); sending SMS to numbers...numbers.*/ } abstract public void destroyConnectionWithYourTower(); public void checkForDND(){ //check for number present in DND. } public void checkForTelecomRules(){ //Check for telecom rules } } class Vodafone extends SMSSender{ @Override public void eastablishConnectionWithYourTower() { //connecting using Vodafone way } @Override public void destroyConnectionWithYourTower() { //destroying connection using Vodafone way } } class Airtel extends SMSSender{ @Override public void eastablishConnectionWithYourTower() { //connecting using Airtel way } @Override public void destroyConnectionWithYourTower() { //destroying connection using Airtel way } } Let’s say, I am the principal of a college and I want details of each department of the college. My college has various departments like Art, science, commerce, etc. I want to know the department name, how many teachers are in each department(mandatory information), and some additional information. So, I will create a structure that will be followed by each department. I will create an abstract class with an abstract method that will be inherited by each department. So each department must provide the implementation of the abstract method.
To summarize,
For Interface:Interface is used when you don't know anything about implementation but know the contract that implementer should have to accomplish the task.
For Abstract class:Abstract class is used when you know partial implementation, where say out of 5 methods, you know implementation of 3 methods and don't know implemenatation of 2 methods in that case 2 methods will be abstract and you need to rely on implementer as a contract to must provide body of abstract methods to accomplish the task.